package algo3.grupo3.modelo;

import java.util.LinkedList;

public class AreaCasillas {

	private Casilla primeraCasilla,casillaSuperiorDerecha,casillaInferiorIzquierda;
	private int cantidadCasillas;
	private int posicionUltimaCasillaHorizontal, posicionUltimaCasillaVertical;
	private LinkedList<Enemigo> enemigosEnJuego= new LinkedList<Enemigo>();
	
	public AreaCasillas(){
		primeraCasilla = new Casilla();
		primeraCasilla.setearPosicionX(0);
		primeraCasilla.setearPosicionY(0);
		casillaSuperiorDerecha = primeraCasilla;
		casillaInferiorIzquierda= primeraCasilla;
		this.posicionUltimaCasillaHorizontal = this.posicionUltimaCasillaVertical = 0;
		cantidadCasillas = 1;
	}//fin de constructor
	
	public AreaCasillas(int filas, int columnas){
		primeraCasilla = new Casilla();
		primeraCasilla.setearPosicionX(0);
		primeraCasilla.setearPosicionY(0);
		casillaSuperiorDerecha = primeraCasilla;
		casillaInferiorIzquierda = primeraCasilla;
		this.posicionUltimaCasillaHorizontal = this.posicionUltimaCasillaVertical = 0;
		cantidadCasillas = 1;
		cargarFilasYColumnas(filas,columnas);
		
	}
	
	public void agregarEnemigo(Enemigo unEnemigo){
		if(unEnemigo == null){
			return;
		}
		
		/*if(this.enemigosEnJuego == null){
			this.enemigosEnJuego = new LinkedList<Enemigo>();
		}*/
		
		this.enemigosEnJuego.add(unEnemigo);
	}
	
	public boolean todosLosEnemigosEstanMuertos(){
		int i = 0;
		boolean hayUnEnemigoVivo = false;
		
		if(this.enemigosEnJuego.isEmpty()){
			return true;//no hay enemigos en juego
		}
		
		while (i < this.enemigosEnJuego.size() && hayUnEnemigoVivo == false) {
			if (this.enemigosEnJuego.get(i).sigueActivo() == true){
				hayUnEnemigoVivo = true;
			}
			i++;
		}
		
		return (!hayUnEnemigoVivo);
	}
	
	private void cargarFilasYColumnas(int filas, int columnas){
		if(filas <= 0 || columnas <= 0)
			return;
		for(int f = 0; f < filas; f++)
			this.agregarFila();
		for(int c = 0; c < columnas ; c++)
			this.agregarColumna();
	}
	
	public Casilla obtenerPrimeraCasilla(){
		return this.primeraCasilla;
	}//fin de obtenerPrimeraCasilla
	
	public boolean areaEsNula(){
		return (this.cantidadCasillas == 0);
	}//fin de areaEsNula
	
	public void agregarColumna(){
		
		Casilla casillaActual= this.casillaSuperiorDerecha;
		Casilla anteUltimaCasillaHorizontal, ultimaCasillaHorizontal, casillaVincularVerticalmente;
		anteUltimaCasillaHorizontal = casillaActual;
		posicionUltimaCasillaHorizontal++;
		for(int y=0 ; y<=posicionUltimaCasillaVertical ; y++){
			agregarCasillaADerecha(casillaActual);
			cantidadCasillas++;
			casillaActual= casillaActual.obtenerCasillaInferior();
		}
		casillaSuperiorDerecha= casillaSuperiorDerecha.obtenerCasillaDerecha();
		for(int y= 0; y<posicionUltimaCasillaVertical ; y++){
			ultimaCasillaHorizontal= anteUltimaCasillaHorizontal.obtenerCasillaDerecha();
			anteUltimaCasillaHorizontal= anteUltimaCasillaHorizontal.obtenerCasillaInferior();
			casillaVincularVerticalmente= anteUltimaCasillaHorizontal.obtenerCasillaDerecha();
			vincularCasillasVerticalmente(ultimaCasillaHorizontal,casillaVincularVerticalmente);
		}
		
		
	}//fin de agregarColumna
	
	public void agregarFila(){
		
		Casilla casillaActual= this.casillaInferiorIzquierda;
		Casilla anteUltimaCasillaVertical, ultimaCasillaVertical, casillaVincularHorizontalmente;
		anteUltimaCasillaVertical= casillaActual;
		posicionUltimaCasillaVertical++;
		for(int x=0 ; x<=posicionUltimaCasillaHorizontal ; x++){
			agregarCasillaAbajo(casillaActual);
			cantidadCasillas++;
			casillaActual= casillaActual.obtenerCasillaDerecha();
		}
		casillaInferiorIzquierda= casillaInferiorIzquierda.obtenerCasillaInferior();
		for(int x= 0; x<posicionUltimaCasillaHorizontal ; x++){
			ultimaCasillaVertical= anteUltimaCasillaVertical.obtenerCasillaInferior();
			anteUltimaCasillaVertical=anteUltimaCasillaVertical.obtenerCasillaDerecha();
			casillaVincularHorizontalmente= anteUltimaCasillaVertical.obtenerCasillaInferior();
			vincularCasillasHorizontalmente(ultimaCasillaVertical,casillaVincularHorizontalmente);
		}
		
	}//fin de agregarFila
	
	private void agregarCasillaADerecha(Casilla casillaActual){
		if(casillaActual == null)
			return;
		Casilla casillaNueva= new Casilla();
		casillaActual.setearCasillaDerecha(casillaNueva);
		casillaNueva.setearCasillaIzquierda(casillaActual);
		casillaNueva.setearPosicionX( casillaActual.obtenerPosicion()[0]+1 );
		casillaNueva.setearPosicionY( casillaActual.obtenerPosicion()[1] );
	}
	
	
	
	public void agregarCasillaAbajo(Casilla casillaActual){
		if(casillaActual== null)
			return;
		Casilla casillaNueva= new Casilla();
		this.vincularCasillasVerticalmente(casillaActual, casillaNueva);
		casillaNueva.setearPosicionX(casillaActual.obtenerPosicion()[0]);
		casillaNueva.setearPosicionY( casillaActual.obtenerPosicion()[1]+1 );
	}
	
	private void vincularCasillasVerticalmente(Casilla casillaSuperior, Casilla casillaInferior){
		if(casillaSuperior==null || casillaInferior == null)
			return;
		casillaSuperior.setearCasillaInferior(casillaInferior);
		casillaInferior.setearCasillaSuperior(casillaSuperior);
	}
	
	private void vincularCasillasHorizontalmente(Casilla casillaIzquierda, Casilla casillaDerecha){
		if(casillaDerecha==null || casillaIzquierda== null)
			return;
		casillaIzquierda.setearCasillaDerecha(casillaDerecha);
		casillaDerecha.setearCasillaIzquierda(casillaIzquierda);
	}
	
	public int obtenerCantidadCasillas(){
		return this.cantidadCasillas;
	}
	
	public int obtenerCantidadFilas(){
		return (this.posicionUltimaCasillaVertical+1);
	}
	
	public int obtenerCantidadColumnas(){
		return (this.posicionUltimaCasillaHorizontal+1);
	}
	
	public Casilla obtenerCasillaEn(int posX, int posY){
		Casilla casillaActual= this.primeraCasilla;
		if(posX > this.posicionUltimaCasillaHorizontal || posY > this.posicionUltimaCasillaVertical)
			return null;
		for(int i=0; i<posX ; i++)
			casillaActual= casillaActual.obtenerCasillaDerecha();
		for(int j=0; j<posY ; j++)
			casillaActual= casillaActual.obtenerCasillaInferior();
		return casillaActual;
	}
	
}//fin de AreaCasillas
